#include "kernel/types.h"
#include "kernel/stat.h"
#include "kernel/fs.h"
#include "user/user.h"

void getfilename(const char* path, void* out) {
    const char* p = path + strlen(path);
    while (p != path) {
        --p;

        if (*p == '/')
            break;
    }

    if (p == path)
        return;
    
    memmove(out, ++p, DIRSIZ);
}

void find(char* path, char* target) {
    int fd;
    struct stat st;

    if((fd = open(path, 0)) < 0){
        fprintf(2, "find: cannot open %s\n", path);
        return;
    }

    if(fstat(fd, &st) < 0){
        fprintf(2, "find: cannot stat %s\n", path);
        close(fd);
        return;
    }
    
    char filepath[512], *p;
    struct dirent de;
    char filename[DIRSIZ];
    switch (st.type)
    {
    case T_FILE:
        getfilename(path, filename);

        if (strcmp(filename, target) != 0)
            break;

        strcpy(filepath, path);
        p = filepath + strlen(path);
        *p = '\n';

        printf(filepath);
        break;
    
    case T_DIR:
        //copy from ls.c
        if(strlen(path) + 1 + DIRSIZ + 1 > sizeof(filepath)){
            printf("ls: path too long\n");
            break;
        }
        strcpy(filepath, path);
        p = filepath + strlen(filepath);
        *p++ = '/';

        //read offset sizeof(dirent)
        //to read sub file/directory in the directory
        while(read(fd, &de, sizeof(de)) == sizeof(de)){
            if(de.inum == 0 || strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0)
                continue;
            memmove(p, de.name, DIRSIZ);
            p[DIRSIZ] = 0;
            
            find(filepath, target);
        }
        break;
    }

    close(fd);
}

int main(int argc, char* argv[]) {
    if (argc != 3){
        printf("find [directory name] [file name]\n");
        exit(0);
    }

    printf("directory name: %s, file name: %s\n", argv[1], argv[2]);

    find(argv[1], argv[2]);
    exit(0);
}   